package com.shiwaixiangcun.authz;

import com.shiwaixiangcun.utils.MonkeyUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 工具类
 * Created by fyc on 2017/3/1.
 */
public class ApplicationUtils {

    /**
     * 获取明天的日期
     *
     * @return String
     */
    public static String getTomorrow(Date now) {
        Calendar c = MonkeyUtils.getCalendar(now);
        int today = c.get(Calendar.DATE);
        int year = Integer.valueOf(ApplicationUtils.parseDateString(now, "yyyy"));
        int month = Integer.valueOf(ApplicationUtils.parseDateString(now, "MM"));
        int day = MonkeyUtils.getDaysInMonth(year, month);
        if (today == day) {
            // 跨月
            month += 1;
            if (month == 13) {
                // 跨年
                year += 1;
                month = 1;
            }
            today = 1;
        } else {
            today += 1;
        }
        Date tomorrow = MonkeyUtils.getDate(year, month - 1, today);
        return ApplicationUtils.parseDateString(tomorrow, "yyyy-MM-dd");
    }

    /**
     * 保留一位小数，向下舍入
     */
    public static Double floorFormat(Double d) {
        DecimalFormat df = new DecimalFormat("######0.00"); // 保留两位小数，四舍五入
        d = Double.valueOf(df.format(d));
        return Math.ceil(d * 10) / 10;
    }

    /**
     * 保留一位小数，向上舍入
     */
    public static Double ceilFormat(Double d) {
        DecimalFormat df = new DecimalFormat("######0.00"); // 保留两位小数，四舍五入
        d = Double.valueOf(df.format(d));
        return Math.ceil(d * 10) / 10;
    }

    /**
     * String转List<String>
     *
     * @param separator 分隔符
     */
    public static List<String> stringToListString(String str, String separator) {
        List<String> result;
        String[] strArr = str.split(separator);
        result = Arrays.asList(strArr);

        return result;
    }

    /**
     * 去除重复的值
     * 注意： 值类型可直接得到结果，
     * 引用类型请在实体类中重写equals方法才能保证数据正确性
     */
    public static <T> List removeRepValue(List<T> list) {
        List<T> listTemp = new ArrayList<T>();
        Iterator<T> it = list.iterator();
        while (it.hasNext()) {
            T num = it.next();
            if (listTemp.contains(num)) {
                it.remove();
            } else {
                listTemp.add(num);
            }
        }
        return list;
    }

    /**
     * 将idList从StringList转化为LongList
     *
     * @param separator List中的字符串之间的分隔符号, 如果List中的字符串没有分隔符，参数为null
     */
    public static List<Long> listStringTolistLong(List<String> strList, String separator) {
        List<Long> idList = new ArrayList<>();
        for (String str : strList) {
            if (!ApplicationUtils.isEmpty(str)) {
                Long i = 0L;
                if (isEmpty(separator)) {
                    i = Long.valueOf(str);
                    idList.add(i);
                } else {
                    if (str.contains(separator)) {
                        String intValue[] = str.split(",");
                        for (String value : intValue) {
                            idList.add(Long.valueOf(value));
                        }
                    } else {
                        i = Long.valueOf(str);
                        idList.add(i);
                    }
                }
            }
        }
        return idList;
    }



    /**
     * 计算身份证 校验码
     */
    public static String calcValidationCode(String idCard) {
        String result = "";
        int[] x = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] y = {'1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2'};
        int sum = 0;
        for (int i = 0; i < idCard.length() - 1; i++) {
            int n = idCard.charAt(i) - 48;
            sum += n * x[i];
        }
        sum = sum % 11;
        result = String.valueOf(y[sum]);

        return result;
    }

    /**
     * 判断出生日期是否正确
     */
    public static boolean validBirthday(String birthday) {

        // 当前日期
        String nowDate = getCurrentDateString();
        String nowYear = nowDate.substring(0, 4);
        String nowMonth = nowDate.substring(5, 7);
        String nowDay = nowDate.substring(8, 10);

        // 出生日期
        String year = birthday.substring(0, 4);
        String month = birthday.substring(5, 7);
        String day = birthday.substring(8, 10);

        // 判断 month 是否正确
        if (Integer.valueOf(month) > 12) {
            return false;
        }
        // 判断 天数 是否大于当前年月的天数
        int monthDay = MonkeyUtils.getDaysInMonth(Integer.valueOf(year), Integer.valueOf(month));
        if (Integer.valueOf(day) > monthDay) {
            return false;
        }

        int y = compareStrNumber(year, nowYear);
        int m = compareStrNumber(month, nowMonth);
        int d = compareStrNumber(day, nowDay);

        // 判断出生日期是否大于当前日期
        if (y == 1) {
            return false;
        }
        if (y == 0 && m == 1) {
            return false;
        }
        if (y == 0 && m == 0 && d == 1) {
            return false;
        }

        return true;

    }

    /**
     * 判断纯数字字符串大小
     */
    public static int compareStrNumber(String str1, String str2) {
        int result = 0;
        int num1 = Integer.valueOf(str1);
        int num2 = Integer.valueOf(str2);
        if (num1 > num2) {
            result = 1;
        }
        if (num1 < num2) {
            result = -1;
        }
        if (num1 == num2) {
            result = 0;
        }
        return result;
    }

    /**
     * 判断字符串是否为空
     */
    public static boolean isEmpty(String str) {

        if (str == null || "".equals(str.trim()) || str.isEmpty()) {
            return true;
        }
        return false;
    }

    /**
     * 判断list是否为空
     *
     * @param <T>
     */
    public static <T> boolean isEmpty(List<T> list) {

        if (list == null || list.size() == 0 || list.isEmpty()) {

            return true;
        }

        return false;
    }

    /**
     * 根据需要的字符串长度，填充0
     *
     * @param str       原字符串
     * @param needLenth 需要的字符串长度
     * @return
     */
    public static String fillZero(String str, int needLenth) {
        String result = "";
        int numLenth = str.length();

        // 计算需要补0的个数
        int zeroCount = needLenth - numLenth;

        for (int i = 0; i < zeroCount; i++) {
            // 补0
            result += "0";
        }
        result += str;

        return result;
    }


    /**
     * 判断首字符是否是字母
     */
    public static boolean headIsCharacter(String str) {
        str = str.substring(0, 1);
        String reg = "[a-zA-Z]";
        boolean isCract = str.matches(reg);
        return isCract;
    }

    /**
     * 判断字符串是否全为数字
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     * 手机号验证
     */
    public static boolean isMobile(String mobile) {
        String reg = "(^0{0,1}1[3|4|5|6|7|8|9][0-9]{9}$)";
        boolean isMobile = mobile.matches(reg);
        return isMobile;

    }

    /**
     * 获取当前日期字符串.
     */
    public static String getCurrentDateString() {
        return parseDateString(new Date(), "yyyy-MM-dd");
    }

    /**
     * 格式化日期到指定的格式
     *
     * @param date   日期
     * @param format 指定的日期格式
     * @return
     */
    public static String parseDateString(Date date, String format) {
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    /**
     * 格式化日期到指定的格式
     *
     * @param date   日期
     * @param format 指定的日期格式
     * @return
     */
    public static String parseDateString(String date, String format) {
        Date date1 = parseDate(date);
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date1);
    }

    /**
     * 格式化时间字符串 为 yyyy-MM-dd 格式
     *
     * @param date 时间字符串
     * @return
     */
    public static String parseDateString(String date) {
        Date time = parseDate(date);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(time);
    }

    /**
     * 日期比较
     *
     * @param date1
     * @param date2
     * @return 返回值为1: date1 > date2   返回值为-1: date1 < date2   返回值为0: date1 == date2
     */
    public static int compareDate(String date1, String date2) {

        try {
            Date dt1 = parseDate(date1);
            Date dt2 = parseDate(date2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算指定时间格式的 相差小时数
     *
     * @param datetime1
     * @param datetime2
     * @param pattern
     * @return
     */
    public static Double calcRealHours(String datetime1, String datetime2, String pattern) {
        if (MonkeyUtils.isEmpty(datetime1) || MonkeyUtils.isEmpty(datetime2)) {
            return 0d;
        }
        Date date1 = MonkeyUtils.getDate(datetime1, pattern);
        Date date2 = MonkeyUtils.getDate(datetime2, pattern);
        DecimalFormat df = new DecimalFormat("######0.0");
        double temp; //相差毫秒数
        if (compareDate(datetime1, datetime2) >= 0) {
            temp = date1.getTime() - date2.getTime();
        } else {
            temp = date2.getTime() - date1.getTime();
        }
        double hours = temp / 1000 / 3600;
        return Double.parseDouble(df.format(hours));
    }

    /**
     * 通用转换字符串为日期时间.
     */
    public static Date parseDate(String isDateString) {
        Date tcDate = null;
        if (!isEmpty(isDateString)) {
            if (isDateString.contains(" ")) {
                if (isDateString.contains(":")) {
                    // 包含时间
                    try {
                        SimpleDateFormat tcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        tcDate = tcDateFormat.parse(isDateString);
                        return tcDate;
                    } catch (Exception e) {

                    }
                    try {
                        SimpleDateFormat tcDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                        tcDate = tcDateFormat.parse(isDateString);
                        return tcDate;
                    } catch (Exception e) {

                    }
                } else {
                    // 不包含时间
                    try {
                        SimpleDateFormat tcDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        tcDate = tcDateFormat.parse(isDateString);
                        return tcDate;
                    } catch (Exception e) {

                    }
                }
            } else {
                try {
                    SimpleDateFormat tcDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    tcDate = tcDateFormat.parse(isDateString);
                    return tcDate;
                } catch (Exception e) {

                }

                try {
                    SimpleDateFormat tcDateFormat = new SimpleDateFormat("公元yyyy年MM月dd日");
                    tcDate = tcDateFormat.parse(isDateString);
                    return tcDate;
                } catch (Exception e) {

                }

                try {
                    SimpleDateFormat tcDateFormat = new SimpleDateFormat("yyyy-MM");
                    tcDate = tcDateFormat.parse(isDateString);
                    return tcDate;
                } catch (Exception e) {

                }
                try {
                    SimpleDateFormat tcDateFormat = new SimpleDateFormat("HH:mm");
                    tcDate = tcDateFormat.parse(isDateString);
                    return tcDate;
                } catch (Exception e) {

                }
            }
        }
        return tcDate;
    }


    public static String removeTag(String htmlStr) {
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; // script
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; // style
        String regEx_html = "<[^>]+>"; // HTML tag
        String regEx_space = "\\s+|\t|\r|\n";// other characters
        String regEx_special = "\\&[a-zA-Z]{1,10};";

        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll("");

        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll("");

        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll("");

        Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE);
        Matcher m_space = p_space.matcher(htmlStr);
        htmlStr = m_space.replaceAll(" ");

        Pattern p_special = Pattern.compile(regEx_special, Pattern.CASE_INSENSITIVE);
        Matcher m_sepcial = p_special.matcher(htmlStr);
        htmlStr = m_sepcial.replaceAll("");

        return htmlStr;
    }


    /**
     * 利用时间戳生成流水号
     * 14位时间戳 + 4位小数
     *
     * @return string
     */
    public static String getNumberForPK() {
        String number = "";
        Long time = System.currentTimeMillis();
        int random = (int) (Math.random() * (9999 - 1000 + 1)) + 1000;
        number = time.toString() + random;
        return number;
    }

    public static <M> List<M> limitList(int pageIndex, int pageSize, int total, List<M> data) {
        // 根据 条件获取到 分页的结构和数据
        List<M> list;
        if (total < pageSize) {
            list = data.subList(pageIndex, total);
        } else {
            int toSize = pageIndex + pageSize;
            if (toSize > total) {
                toSize = pageIndex + total % pageSize;
            }
            list = data.subList(pageIndex, toSize);
        }
        return list;
    }

    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }




}
